home *** CD-ROM | disk | FTP | other *** search
- /*
- * subsample.c
- *
- * Practical Algorithms for Image Analysis
- *
- * Copyright (c) 1997, 1998, 1999 MLMSoftwareGroup, LLC
- */
-
- /* SUBSAMPLE: program performs image subsampling after low-pass filtering
- * usage: subsample inimg outimg [-r subsample rate]
- * [-d DEGREE_FILTERING] [-q quickFlag] [-L]
- */
-
- #define DFLT_SUBRATE 2 /* subsample by 2 is default */
- #define DFLT_DEG_FLTR 0.5 /* default degree of filtering */
- #define RECT_CUTOFF 0.443883 /* factor to calc. 3dB cutoff freq */
- #define GAUSS_CUTOFF 0.832555 /* factor to calc. 3dB cutoff freq */
- #define ROUNDUP 0.99999 /* for rounding up integer */
- #define NORM 1000.0 /* normaliz. factor to integerize */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <images.h>
- #include <tiffimage.h>
- #include <math.h>
- #include <string.h>
- extern void print_sos_lic ();
-
- long convolve1r (Image *, Image *, long *, long, long);
- long smoothr (Image *, Image *, long, long);
- long input (int, char **, long *, double *, short *);
- long usage (short);
-
- main (argc, argv)
- int argc;
- char *argv[];
- {
- Image *imgI, *imgO; /* input, output image structures */
- long width, height; /* image size */
- double cutoff; /* low-pass cutoff frequency */
- long fltrSize; /* filter mask size */
- long rSubsample; /* subsample rate */
- double degFltr; /* degree of filtering [0.0 - 1.0] */
- double stdDev; /* std. deviation param. of Gaussian */
- long *fltr; /* 1D filter mask */
- long midFltr; /* middle filter coefficient */
- short quickFlag; /* for quick and dirty rect. filter */
- long i;
-
- if (input (argc, argv, &rSubsample, °Fltr, &quickFlag) < 0)
- return (-1);
-
- /* open input image */
- imgI = ImageIn (argv[1]);
- height = ImageGetHeight (imgI);
- width = ImageGetWidth (imgI);
- printf ("Input mage size is %dx%d.\n", width, height);
-
- /* determine filter size and coefficients */
- if (degFltr == 0.0)
- cutoff = 100.0;
- else
- cutoff = 0.5 / (rSubsample * degFltr);
- if (quickFlag) /* rectangular filter window */
- fltrSize = (long) (RECT_CUTOFF / cutoff + ROUNDUP);
- else { /* Gaussian filter window */
- stdDev = GAUSS_CUTOFF / cutoff;
- fltrSize = (long) (3.0 / (2.0 * cutoff) + 0.5);
- }
- if ((fltrSize % 2) == 0)
- fltrSize += 1;
- printf ("Filter 3dB cutoff frequency is %5.2f and filter size is %dx%d.\n",
- cutoff, fltrSize, fltrSize);
-
- if (!quickFlag) {
- fltr = (long *) calloc (fltrSize, sizeof (*fltr));
- midFltr = fltrSize / 2;
- for (i = 0; i <= midFltr; i++)
- fltr[i + midFltr] = fltr[midFltr - i]
- = (long) (NORM * exp (-i * i / (2.0 * stdDev * stdDev)));
- }
-
- /* perform filtering */
- imgO = ImageAlloc (height / rSubsample + 1, width / rSubsample + 1, 8);
- if (quickFlag)
- smoothr (imgI, imgO, fltrSize, rSubsample);
- else
- convolve1r (imgI, imgO, fltr, fltrSize, rSubsample);
-
- /* output subsampled image */
- printf ("Output image size is %dx%d.\n",
- width / rSubsample + 1, height / rSubsample + 1);
- ImageOut (argv[2], imgO);
-
- return (0);
- }
-
-
- /* USAGE: function gives instructions on usage of program
- * usage: usage (flag)
- * When flag is 1, the long message is given, 0 gives short.
- */
-
- long
- usage (flag)
- short flag; /* flag =1 for long message; =0 for short message */
- {
-
- /* print short usage message or long */
- printf ("USAGE: subsample inimg outimg [-r SAMPLE_RATE <%d>]\n", DFLT_SUBRATE);
- printf (" [-d DEG_FILTERING <%3.1f>] [-q] [-L]\n", DFLT_DEG_FLTR);
- if (flag == 0)
- return (-1);
-
- printf ("\nsubsample performs subsampling after low-pass\n");
- printf ("filtering on image; the default filter is a Gaussian\n\n");
- printf ("ARGUMENTS:\n");
- printf (" inimg: input image filename (TIF)\n");
- printf (" outimg: output image filename (TIF)\n\n");
- printf ("OPTIONS:\n");
- printf (" -r SAMPLE_RATE: rate of image reduction; the default setting\n");
- printf (" -r %d reduces rate to reduce image by 2 in x and y).\n", DFLT_SUBRATE);
- printf (" -d DEG_FILTERING: value set between 0.0 and 1.0 controlling\n");
- printf (" the degree of low-pass filtering; a value\n");
- printf (" of 1.0 produces maximum filtering to reduce aliasing,\n");
- printf (" but may lead to blurring;\n");
- printf (" a value of 0.0 does no filtering at the risk of aliasing.\n");
- printf (" the default is %3.1f.\n", DFLT_DEG_FLTR);
- printf (" -q: when set, performs quick low-pass filtering \n");
- printf (" rectangular filter rather than Gaussian filter;\n");
- printf (" the former is faster but doesn't produce equally\n");
- printf (" good results as does the latter.\n");
- printf (" -L: print Software License for this module\n");
- return (-1);
- }
-
-
- /* INPUT: function reads input parameters
- * usage: input (argc, argv, &rSubsample,
- * °Fltr, &quickFlag)
- */
-
- #define USAGE_EXIT(VALUE) {usage (VALUE); return (-1);}
-
- long
- input (argc, argv, rSubsample, degFltr, quickFlag)
- int argc;
- char *argv[];
- long *rSubsample; /* subsample rate */
- double *degFltr; /* degree of filtering [0.0 - 1.0] */
- short *quickFlag; /* for quick and dirty rect. filter */
- {
- long n;
-
- if (argc < 3)
- USAGE_EXIT (-1);
-
- *rSubsample = DFLT_SUBRATE;
- *degFltr = DFLT_DEG_FLTR;
- *quickFlag = 0;
-
- for (n = 3; n < argc; n++) {
- if (strcmp (argv[n], "-r") == 0) {
- if (++n == argc || argv[n][0] == '-')
- USAGE_EXIT (-1);
- *rSubsample = atol (argv[n]);
- }
- else if (strcmp (argv[n], "-d") == 0) {
- if (++n == argc || argv[n][0] == '-')
- USAGE_EXIT (-1);
- *degFltr = atof (argv[n]);
- }
- else if (strcmp (argv[n], "-q") == 0)
- *quickFlag = 1;
- else if (strcmp (argv[n], "-L") == 0) {
- print_sos_lic ();
- exit (0);
- }
- else
- USAGE_EXIT (-1);
- }
-
- return (0);
- }
-